import smbus
import time

# Get I2C bus
bus = smbus.SMBus(1)

# I2C address of the device
# I2C 对应内存地址
ADS1115_IIC_ADDRESS0				= 0x48
ADS1115_IIC_ADDRESS1				= 0x49

# ADS1115 注册（转换）寄存器
ADS1115_REG_POINTER_CONVERT			= 0x00 
# 转换寄存器
ADS1115_REG_POINTER_CONFIG			= 0x01 
# 配置寄存器
ADS1115_REG_POINTER_LOWTHRESH		= 0x02 
# Lo_thresh
ADS1115_REG_POINTER_HITHRESH		= 0x03 
# Hi_thresh

# ADS1115 配置寄存器
ADS1115_REG_CONFIG_OS_NOEFFECT		= 0x00 # 忽略，无效
ADS1115_REG_CONFIG_OS_SINGLE		= 0x80 # 开始一个单次转换
ADS1115_REG_CONFIG_MUX_DIFF_0_1		= 0x00 # 差分 P = AIN0, N = AIN1 (default)
ADS1115_REG_CONFIG_MUX_DIFF_0_3		= 0x10 # 差分 P = AIN0, N = AIN3
ADS1115_REG_CONFIG_MUX_DIFF_1_3		= 0x20 # 差分 P = AIN1, N = AIN3
ADS1115_REG_CONFIG_MUX_DIFF_2_3		= 0x30 # 差分 P = AIN2, N = AIN3
ADS1115_REG_CONFIG_MUX_SINGLE_0		= 0x40 # 单端 P = AIN0, N = GND
ADS1115_REG_CONFIG_MUX_SINGLE_1		= 0x50 # 单端 P = AIN1, N = GND
ADS1115_REG_CONFIG_MUX_SINGLE_2		= 0x60 # 单端 P = AIN2, N = GND
ADS1115_REG_CONFIG_MUX_SINGLE_3		= 0x70 # 单端 P = AIN3, N = GND
ADS1115_REG_CONFIG_PGA_6_144V		= 0x00 # +/-6.144V range = Gain 2/3
ADS1115_REG_CONFIG_PGA_4_096V		= 0x02 # +/-4.096V range = Gain 1
ADS1115_REG_CONFIG_PGA_2_048V		= 0x04 # +/-2.048V range = Gain 2 (default)
ADS1115_REG_CONFIG_PGA_1_024V		= 0x06 # +/-1.024V range = Gain 4
ADS1115_REG_CONFIG_PGA_0_512V		= 0x08 # +/-0.512V range = Gain 8
ADS1115_REG_CONFIG_PGA_0_256V		= 0x0A # +/-0.256V range = Gain 16
ADS1115_REG_CONFIG_MODE_CONTIN		= 0x00 # 连续转换模式
ADS1115_REG_CONFIG_MODE_SINGLE		= 0x01 # 低电压单发模式 (default)
ADS1115_REG_CONFIG_DR_8SPS			= 0x00 # 8 samples per second
ADS1115_REG_CONFIG_DR_16SPS			= 0x20 # 16 samples per second
ADS1115_REG_CONFIG_DR_32SPS			= 0x40 # 32 samples per second
ADS1115_REG_CONFIG_DR_64SPS			= 0x60 # 64 samples per second
ADS1115_REG_CONFIG_DR_128SPS		= 0x80 # 128 samples per second (default)
ADS1115_REG_CONFIG_DR_250SPS		= 0xA0 # 250 samples per second
ADS1115_REG_CONFIG_DR_475SPS		= 0xC0 # 475 samples per second
ADS1115_REG_CONFIG_DR_860SPS		= 0xE0 # 860 samples per second
ADS1115_REG_CONFIG_CMODE_TRAD		= 0x00 # 具有滞后功能的传统比较器 (default)
ADS1115_REG_CONFIG_CMODE_WINDOW		= 0x10 # 窗口比较器
ADS1115_REG_CONFIG_CPOL_ACTVLOW		= 0x00 # 激活时ALERT / RDY引脚为低电平 (default)
ADS1115_REG_CONFIG_CPOL_ACTVHI		= 0x08 # 激活时ALERT / RDY引脚为高电平
ADS1115_REG_CONFIG_CLAT_NONLAT		= 0x00 # 非锁存比较器 (default)
ADS1115_REG_CONFIG_CLAT_LATCH		= 0x04 # 锁存比较器
ADS1115_REG_CONFIG_CQUE_1CONV		= 0x00 # 1次转换后确认ALERT / RDY
ADS1115_REG_CONFIG_CQUE_2CONV		= 0x01 # 2次转换后确认ALERT / RDY
ADS1115_REG_CONFIG_CQUE_4CONV		= 0x02 # 3次转换后确认ALERT / RDY
ADS1115_REG_CONFIG_CQUE_NONE		= 0x03 # 禁用比较器并将ALERT / RDY置于高电平状态(default)

mygain=0x02
coefficient=0.125
addr_G=ADS1115_IIC_ADDRESS0
#首先从S0开始
class ADS1115():
	def setGain(self,gain):
		#获取需要输入的频道
		global mygain
		global coefficient
		mygain=gain
		if mygain == ADS1115_REG_CONFIG_PGA_6_144V:
			coefficient = 0.1875
		elif mygain == ADS1115_REG_CONFIG_PGA_4_096V:
			coefficient = 0.125
		elif mygain == ADS1115_REG_CONFIG_PGA_2_048V:
			coefficient = 0.0625
		elif mygain == ADS1115_REG_CONFIG_PGA_1_024V:
			coefficient = 0.03125
		elif mygain == ADS1115_REG_CONFIG_PGA_0_512V:
			coefficient = 0.015625
		elif  mygain == ADS1115_REG_CONFIG_PGA_0_256V:
			coefficient = 0.0078125
		else:
			coefficient = 0.125
	def setAddr_ADS1115(self,addr):
		global addr_G
		addr_G=addr
	def setChannel(self,channel):
		global mygain
		"""从0-3选择要使用的频道
		单端输出
		0 : AINP = AIN0 and AINN = GND
		1 : AINP = AIN1 and AINN = GND
		2 : AINP = AIN2 and AINN = GND
		3 : AINP = AIN3 and AINN = GND
		差分输出
		0 : AINP = AIN0 and AINN = AIN1
		1 : AINP = AIN0 and AINN = AIN3
		2 : AINP = AIN1 and AINN = AIN3
		3 : AINP = AIN2 and AINN = AIN3
		"""
		self.channel = channel
		while self.channel > 3 :
			self.channel = 0
		
		return self.channel
	
	def setSingle(self):
		#配置,单次读取
		global addr_G
		if self.channel == 0:
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_SINGLE_0 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]
		elif self.channel == 1:
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_SINGLE_1 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]
		elif self.channel == 2:
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_SINGLE_2 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]
		elif self.channel == 3:
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_SINGLE_3 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]
		
		bus.write_i2c_block_data(addr_G, ADS1115_REG_POINTER_CONFIG, CONFIG_REG)
		# 设备（端口号），命令，[目标数字，存放数字]
		# write_block_data（）曾出现BCK的问题,原因未知
	
	def setDifferential(self):
		#配置,作为比较器输出
		global addr_G
		if self.channel == 0:
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_DIFF_0_1 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]
		elif self.channel == 1:
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_DIFF_0_3 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]
		elif self.channel == 2:
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_DIFF_1_3 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]
		elif self.channel == 3:
			CONFIG_REG = [ADS1115_REG_CONFIG_OS_SINGLE | ADS1115_REG_CONFIG_MUX_DIFF_2_3 | mygain | ADS1115_REG_CONFIG_MODE_CONTIN, ADS1115_REG_CONFIG_DR_128SPS | ADS1115_REG_CONFIG_CQUE_NONE]
		
		bus.write_i2c_block_data(addr_G, ADS1115_REG_POINTER_CONFIG, CONFIG_REG)
	
	def readValue(self):
		"""
		读取寄存器表
		从 ADS1115_REG_POINTER_CONVERT(0x00), 
		2 bytes
		raw_adc MSB, 
		raw_adc LSB
		"""
		global coefficient
		global addr_G
		data = bus.read_i2c_block_data(addr_G, ADS1115_REG_POINTER_CONVERT, 2)
		# 向I2C设备发送一个写控制字+控制指令（寄存器地址）
		# 再发送一个读控制字，此时I2C从设备内部的读写指针转移到指定的位置
		# 并连续返回多个字节
		# I2C主机读取到一定数量字节内容之后发送无应答NA。
		# 转换数据
		raw_adc = data[0] * 256 + data[1]
		
		if raw_adc > 32767:
			raw_adc -= 65535
		raw_adc = int(float(raw_adc)*coefficient)
		return {'r' : raw_adc}

	def readVoltage(self,channel):
		self.setChannel(channel)
		self.setSingle()
		time.sleep(0.1)
		return self.readValue()

	def ComparatorVoltage(self,channel):
		self.setChannel(channel)
		self.setDifferential()
		time.sleep(0.1)
		return self.readValue()